/****************************************************
 * 创建人:   robin
 * 创建时间: 2023/8/30.030 15:37
 * 项目名称: cpy
 * 文件名称: BufferUtil.java
 * 文件描述: 
 *
 * All rights Reserved, Designed By 德品软件
 * @Copyright:2023-2023
 *
 ********************************************************/
package com.dp.utils;

import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * 包名称：com.dp.utils
 * 类名称：BufferUtil
 * 类描述：
 * 创建人： robin
 * 创建时间：2023/8/30.030 15:37
 */
public class BufferUtil {
    
    public static ByteBuffer cloneByteBuffer(ByteBuffer original) {
        ByteBuffer clone = ByteBuffer.allocate(original.limit() > 0 ? original.limit() : original.capacity()).order(ByteOrder.BIG_ENDIAN);
        original.rewind();  // 因为可能读取过，所以读之前要把position设为0，limit不变
        clone.put(original);
        clone.flip();       // 写之后要把limit设为当前position，再把position设为0，一般在从Buffer读出数据前调用。
        return clone;
    }
    
    public static boolean copyByteBuffer(ByteBuffer original, ByteBuffer target, int length) {
        if ((original.position() + length) <= original.limit()) {
            byte[] bytes = new byte[length];
            original.get(bytes, 0, length);
            target.put(bytes, 0, length);
            return true;
        }
        return false;
    }
    
    public static final BigDecimal hexStringToBigDecimal(String hexString) {
        try {
            float value = Float.intBitsToFloat((int)Long.parseLong(hexString, 16));
            BigDecimal bd = new BigDecimal(Float.toString(value));
            return bd.setScale(2, 1);
        } catch (Exception e) {
            return BigDecimal.ZERO;
        }
    }
    
    public static final BigDecimal doubleHexStringToBigDecimal(String hexString) {
        try {
            return BigDecimal.valueOf(Double.parseDouble(new String(BufferUtil.hexStringToBytes(hexString))));
        } catch (Exception e) {
            return BigDecimal.ZERO;
        }
    }
    
    /**
     * @Author robin
     * @Description ByteBuffer转换为ASCII字符串
     * @Date 2022/8/31.031 16:58
     * @Param bytes byte数组,length 数组内容长度
     * @return 十六进制字符串
     **/
    public static final String byteBufferToAsciiString(ByteBuffer byteBuffer, int length) {
        if ((byteBuffer.position() + length) <= byteBuffer.limit()) {
            byte[] bytes = new byte[length];
            byteBuffer.get(bytes, 0, length);
            try {
                return new String(bytes, "ISO8859-1");
            } catch (Exception e) {
                return "";
            }
        }
        return "";
    }
    
    /**
     * @Author robin
     * @Description ByteBuffer转换为字符串
     * @Date 2022/8/31.031 16:58
     * @Param ByteBuffer byteBuffer,length 数组内容长度
     * @return 十六进制字符串
     **/
    public static final String byteBufferToString(ByteBuffer byteBuffer, int length) {
        if ((byteBuffer.position() + length) <= byteBuffer.limit()) {
            try {
                byte[] bytes = new byte[length];
                byteBuffer.get(bytes, 0, length);
                return new String(bytes);
            } catch (Exception e) {
                return "";
            }
        }
        return "";
    }
    
    /**
     * @Author robin
     * @Description 从ByteBuffer当前位置获取int
     * @Date 2022/8/31.031 16:58
     * @Param ByteBuffer byteBuffer
     * @return int
     **/
    public static final int getInt(ByteBuffer byteBuffer) {
        if ((byteBuffer.position() + Integer.BYTES) <= byteBuffer.limit()) {
            return byteBuffer.getInt();
        }
        return Integer.MIN_VALUE;
    }
    
    /**
     * @Author robin
     * @Description 从ByteBuffer当前位置获取short
     * @Date 2022/8/31.031 16:58
     * @Param ByteBuffer byteBuffer
     * @return short
     **/
    public static final short getShort(ByteBuffer byteBuffer) {
        if ((byteBuffer.position() + Short.BYTES) <= byteBuffer.limit()) {
            return byteBuffer.getShort();
        }
        return Short.MIN_VALUE;
    }
    
    /**
     * @Author robin
     * @Description 从ByteBuffer当前位置获取byte
     * @Date 2022/8/31.031 16:58
     * @Param ByteBuffer byteBuffer
     * @return byte
     **/
    public static final byte getByte(ByteBuffer byteBuffer) {
        if ((byteBuffer.position() + Byte.BYTES) <= byteBuffer.limit()) {
            return byteBuffer.get();
        }
        return Byte.MIN_VALUE;
    }
    
    /**
     * @Author robin
     * @Description 跳过N字节
     * @Date 2022/8/31.031 16:58
     * @Param bytes byte数组,length 数组内容长度
     * @return
     **/
    public static final boolean skip(ByteBuffer byteBuffer, int length) {
        if ((byteBuffer.position() + length) <= byteBuffer.limit()) {
            byte[] bytes = new byte[length];
            byteBuffer.get(bytes, 0, length);
            return true;
        }
        return false;
    }
    
    /**
     * @Author robin
     * @Description ByteBuffer转换为十六进制字符串
     * @Date 2022/8/31.031 16:58
     * @Param bytes byte数组,length 数组内容长度
     * @return 十六进制字符串
     **/
    public static final String byteBufferToHexString(ByteBuffer byteBuffer, int length, boolean space) {
        if ((byteBuffer.position() + length) <= byteBuffer.limit()) {
            try {
                byte[] bytes = new byte[length];
                byteBuffer.get(bytes, 0, length);
                return BufferUtil.bytesToHexString(bytes, length, space);
            } catch (Exception e) {
                return "";
            }
        }
        return "";
    }
    
    /**
     * @Author robin
     * @Description byte数组转换为十六进制字符串
     * @Date 2022/8/31.031 16:58
     * @Param bytes byte数组,length 数组内容长度
     * @return 十六进制字符串
     **/
    public static final String bytesToHexString(byte[] bytes, int length, boolean space) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < length; i++) {
            if (space && (0 == i % 16)) {
                stringBuffer.append('\n');
            }
            if (space) {
                stringBuffer.append(String.format("%02X ", bytes[i]));
            } else {
                stringBuffer.append(String.format("%02X", bytes[i]));
            }
        }
        return stringBuffer.toString();
    }
    
    /**
     * @Author robin
     * @Description 十六进制字符串byte数组转换为十六进制字符串
     * @Date 2022/8/31.031 16:58
     * @Param hexString 十六进制字符串
     * @return ByteBuffer
     **/
    public static final ByteBuffer hexStringToByteBuffer(String hexString) {
        byte[] bytes = BufferUtil.hexStringToBytes(hexString);
        if (bytes != null) {
            ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length).order(ByteOrder.BIG_ENDIAN);
            byteBuffer.put(bytes, 0, bytes.length);
            return byteBuffer;
        }
        return null;
    }
    
    /**
     * @Author robin
     * @Description 十六进制字符串byte数组转换为十六进制字符串
     * @Date 2022/8/31.031 16:58
     * @Param hexString 十六进制字符串
     * @return byte数组
     **/
    public static final byte[] hexStringToBytes(String hexString) {
        try {
            if (StringUtils.isBlank(hexString)) {
                return null;
            }
            StringBuffer stringBuffer = new StringBuffer();
            if (hexString.length() % 2 != 0) {
                stringBuffer.append("0");
            }
            stringBuffer.append(hexString);
            int length = stringBuffer.length() / 2;
            byte[] bytes = new byte[length];
            for (int i = 0; i < length; i++) {
                bytes[i] = (byte) Integer.valueOf(stringBuffer.substring(i * 2, i * 2 + 2), 16).intValue();
            }
            return bytes;
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * @Author robin
     * @Description int转byte[](大字节序)
     * @Date 2022/10/11.011 9:30
     * @Param value 整型数
     * @return 4字节byte数组
     **/
    public static byte[] intToBytes(int value) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) ((value>>24) & 0xFF);
        bytes[1] = (byte) ((value>>16)& 0xFF);
        bytes[2] = (byte) ((value>>8)&0xFF);
        bytes[3] = (byte) (value & 0xFF);
        return bytes;
    }
    
    /**
     * @Author robin
     * @Description short转byte[](大字节序)
     * @Date 2022/10/11.011 9:30
     * @Param value 短整型数
     * @return 2字节byte数组
     **/
    public static byte[] shortToBytes(short value) {
        byte[] bytes = new byte[2];
        bytes[0] = (byte) ((value>>8)&0xFF);
        bytes[1] = (byte) (value & 0xFF);
        return bytes;
    }
    
    /**
     * @Author robin
     * @Description byte[](大字节序)转int
     * @Date 2022/10/11.011 9:30
     * @Param 4字节byte数组
     * @return 整型数
     **/
    public static int bytesToInt(byte[] bytes) {
        return ByteBuffer.wrap(bytes).getInt();
    }
    
    /**
     * @Author robin
     * @Description byte[](大字节序)转short
     * @Date 2022/10/11.011 9:30
     * @Param 短整型数
     * @return 2字节byte数组
     **/
    public static short bytesToShort(byte[] bytes) {
        return ByteBuffer.wrap(bytes).getShort();
    }
    
}
